﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UtilsLib.UtilsType;

namespace UtilsLib.UtilsString
{
    public static class StopWord
    {
        private static bool _isInit = false;
        public static List<string> StopWordFR;
        public static List<string> StopWordEN;
        public static List<string> Punctuation;
        

        public static void Init()
        {
            InitStopWordFr();
            InitStopWordEN();
            InitPunctuation();
            _isInit = true;
        }

        private static void InitStopWordFr()
        {
            StopWordFR = new List<string>();
            StopWordFR.Add("un");
            StopWordFR.Add("une");

            StopWordFR.Add("de");
            StopWordFR.Add("du");
            StopWordFR.Add("des");

            StopWordFR.Add("la");
            StopWordFR.Add("le");
            StopWordFR.Add("les");
            StopWordFR.Add("leur");
            StopWordFR.Add("là");


            StopWordFR.Add("mon");
            StopWordFR.Add("ma");
            StopWordFR.Add("mes");


            StopWordFR.Add("ni");
            StopWordFR.Add("notre");
            StopWordFR.Add("où");


            StopWordFR.Add("par");
            StopWordFR.Add("parce");
            StopWordFR.Add("pourquoi");

            StopWordFR.Add("quand");
            StopWordFR.Add("que");
            StopWordFR.Add("quel");
            StopWordFR.Add("quelle");
            StopWordFR.Add("quelles");
            StopWordFR.Add("quels");
            StopWordFR.Add("qui");

            StopWordFR.Add("sa");
            StopWordFR.Add("sans");
            StopWordFR.Add("ses");
            StopWordFR.Add("si");
            StopWordFR.Add("son");
            StopWordFR.Add("sous");
            StopWordFR.Add("sur");

            StopWordFR.Add("ton");
            StopWordFR.Add("ta");
            StopWordFR.Add("tes");
            StopWordFR.Add("tels");
            StopWordFR.Add("tous");
            StopWordFR.Add("tout");
            StopWordFR.Add("très");
            StopWordFR.Add("tres");

            StopWordFR.Add("il");
            StopWordFR.Add("ils");
            StopWordFR.Add("elle");
            StopWordFR.Add("elles");
            StopWordFR.Add("je");
            StopWordFR.Add("tu");
            StopWordFR.Add("nous");
            StopWordFR.Add("vous");


            StopWordFR.Add("ce");
            StopWordFR.Add("cela");
            StopWordFR.Add("cet");
            StopWordFR.Add("cette");
            StopWordFR.Add("ces");
            StopWordFR.Add("ceux");
            StopWordFR.Add("chaque");
            StopWordFR.Add("ci");
            StopWordFR.Add("comme");

            StopWordFR.Add("pas");
            StopWordFR.Add("y");
            StopWordFR.Add("pour");
            StopWordFR.Add("au");

            StopWordFR.Add("l'");
            StopWordFR.Add("j'");

            StopWordFR.Add("a");
            StopWordFR.Add("ça");


            StopWordFR.Add("mais");
            StopWordFR.Add("ou");
            StopWordFR.Add("et");
            StopWordFR.Add("donc");
            StopWordFR.Add("or");
            StopWordFR.Add("ni");
            StopWordFR.Add("car");


            StopWordFR.Add("alors");
            StopWordFR.Add("avec");
            StopWordFR.Add("dans");
            StopWordFR.Add("en");
            StopWordFR.Add("encore");
            StopWordFR.Add("ici");

            StopWordFR.Add("lequel");
            StopWordFR.Add("laquelle");
            StopWordFR.Add("lesquels");
            StopWordFR.Add("lesquelles");
            StopWordFR.Add("desquels");
            StopWordFR.Add("desquelles");
            StopWordFR.Add("duquel");
            StopWordFR.Add("auquel");
            StopWordFR.Add("auxquels");


        }

        private static void InitStopWordEN()
        {

            StopWordEN = new List<string>();
            StopWordEN.Add("");
        }

        private static void InitPunctuation()
        {

            Punctuation = new List<string>();
            Punctuation.Add("'");
            Punctuation.Add(".");
            Punctuation.Add(",");
            Punctuation.Add(";");
            Punctuation.Add(":");
            Punctuation.Add("!");
            Punctuation.Add("#");
            Punctuation.Add("(");
            Punctuation.Add(")");
            Punctuation.Add("[");
            Punctuation.Add("]");
            Punctuation.Add("{");
            Punctuation.Add("}");
            Punctuation.Add("/");
            Punctuation.Add("\\");
        }

        /// <summary>
        /// Remove the stopWords of the specified language in the content. Return a lowercased string.
        /// </summary>
        /// <param name="content">The content in wich to remove the stopwords</param>
        /// <param name="delimiter">the delimiter used in the content (" ", "_", ...)</param>
        /// <param name="lang">The language of the content</param>
        /// <returns>The lowercased content without the stopwords of the specified language.</returns>
        public static string RemoveStopWords(string content, string delimiter, Language lang)
        {
            return RemoveStopWords(content, delimiter, lang, true);
        }

        /// <summary>
        /// Remove the stopWords of the specified language in the content.
        /// </summary>
        /// <param name="content">The content in wich to remove the stopwords</param>
        /// <param name="delimiter">the delimiter used in the content (" ", "_", ...)</param>
        /// <param name="lang">The language of the content</param>
        /// <param name="toLowerCase">indicate if we need to set the content to lowercase</param>
        /// <returns>The content without the stopwords.</returns>
        public static string RemoveStopWords(string content, string delimiter, Language lang, bool toLowerCase)
        {
            if (!_isInit)
                Init();

            string result = (toLowerCase ? content.ToLower() : content);

            result = RemovePunctuation(result, delimiter, false);

            List<string> StopWords;
            switch (lang)
            {
                case Language.English:
                    StopWords = StopWordEN;
                    break;
                case Language.French:
                    StopWords = StopWordFR;
                    break;
                default:
                    StopWords = StopWordFR;
                    break;
            }

            foreach (string stopWord in StopWords)
            {
                if (result == stopWord)
                    return "";

                //if start by
                if (content.StartsWith(stopWord + delimiter))
                    result = result.Substring((stopWord + delimiter).Length).Trim();

                //middle
                result = result.Replace(delimiter + stopWord + delimiter, delimiter);

                //end by
                if (content.EndsWith(delimiter + stopWord))
                    result = result.Substring(0, result.Length - (delimiter + stopWord).Length);
            }

            return result;
        }

        public static string RemovePunctuation(string content, string delimiter)
        {
            return RemovePunctuation(content, delimiter, true);
        }

        public static string RemovePunctuation(string content, string delimiter, bool toLowerCase)
        {
            if (!_isInit)
                Init();

            string result = (toLowerCase ? content.ToLower() : content);

            foreach (string p in Punctuation)
                result = result.Replace(p, delimiter);

            return result;
        }
    }
}
